/*****************************************************************************
 * Copyright (c) 2019, Nations Technologies Inc.
 *
 * All rights reserved.
 * ****************************************************************************
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Nations' name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ****************************************************************************/

/**
 * @file log.c
 * @author Nations
 * @version v1.0.1
 *
 * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
 */
#include "log.h"
#include <stdio.h>
#include "gd32l23x.h"
#include "gd32l233r_eval.h"

void log_init(void)
{
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_UART3);
#ifndef RX_TEST
    nvic_irq_enable(UART3_IRQn, 0);
#endif
    // close JTAG
#ifndef RX_TEST
    //GPIO_InitStructure.Pin       = LOG_RX_PIN;
    //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    //GPIO_InitPeripheral(LOG_GPIO, &GPIO_InitStructure);
#endif
    /* connect port to USART3 TX */
    gpio_af_set(GPIOC, GPIO_AF_7, GPIO_PIN_10);
    /* connect port to USART3 RX */
    gpio_af_set(GPIOC, GPIO_AF_7, GPIO_PIN_11);
    /* configure USART TX as alternate function push-pull */
    gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
    gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_2);
    /* configure USART RX as alternate function push-pull */
    gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_11);
    gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_3);
    /* USART configure */
    usart_deinit(UART3);
    usart_word_length_set(UART3, USART_WL_8BIT);
    usart_stop_bit_set(UART3, USART_STB_1BIT);
    usart_parity_config(UART3, USART_PM_NONE);
    usart_baudrate_set(UART3, 230400U);
#ifndef RX_TEST
    usart_receive_config(UART3, USART_RECEIVE_ENABLE);
    usart_interrupt_enable(UART3, USART_INT_RBNE);
#endif
    usart_transmit_config(UART3, USART_TRANSMIT_ENABLE);
    usart_enable(UART3);
    // enable uart
    //USART_Enable(LOG_USARTx, ENABLE);
    //RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); // PE2 for LED3
#ifdef RX_TEST
    gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,  GPIO_PIN_11);
    gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,  GPIO_PIN_11);
    /* reset LED GPIO pin */
    gpio_bit_reset(GPIOC, GPIO_PIN_11);
    gpio_bit_set(GPIOC, GPIO_PIN_11);
#endif
}
#if LOG_ENABLE
int bt_total_txlen;
uint8_t send_debug[32];

#ifndef RX_TEST
uint8_t rec_debug[8], rec_index;
uint8_t rec_timeout;



void UART3_IRQHandler()
{
    if(RESET != usart_interrupt_flag_get(UART3, USART_INT_FLAG_RBNE)) {
        /* read one byte from the receive data register */
        rec_debug[rec_index++] = (uint8_t)usart_data_receive(UART3);
        //rec_debug[rec_index++] = USART_ReceiveData(LOG_USARTx);
        rec_index &= 7;
        rec_timeout = 50;
    }
}
#endif
static int is_lr_sent = 0;

int fputc(int ch, FILE* f)
{
    usart_data_transmit(UART3, (uint8_t)ch);

    while(RESET == usart_flag_get(UART3, USART_FLAG_TBE));

    return ch;
}

#ifdef USE_FULL_ASSERT

__WEAK void assert_failed(const uint8_t* expr, const uint8_t* file, uint32_t line)
{
    log_error("assertion failed: `%s` at %s:%d", expr, file, line);

    while(1) {
    }
}
#endif // USE_FULL_ASSERT
#else

int fputc(int ch, FILE* f)
{
    return ch;
}
#endif // LOG_ENABLE
